﻿using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace UDPTestByCore
{
    class Program
    {
        /// <summary>
        /// 用于UDP发送的网络服务类
        /// </summary>
        private static UdpClient udpcSend = null;

        static IPEndPoint localIpep = null;

        public static void Main(string[] args)
        {
            Console.Write("IP:");
            string ip = Console.ReadLine();
            Console.Write("Port:");
            int port = int.Parse(Console.ReadLine());
            localIpep = new IPEndPoint(IPAddress.Parse(ip), port); // 本机IP，指定的端口号

            udpcSend = new UdpClient(localIpep);

            StartReceive();

            // 实名发送
            string msg = null;
            while ((msg = Console.ReadLine()) != null)
            {
                if ("stop" == msg)
                {
                    StopReceive();
                    udpcSend.Close();
                }
                else
                {
                    //string[] arr = Console.ReadLine().Split(' ');
                    Thread thrSend = new Thread(SendMessage);
                    thrSend.Start(msg);
                }
            }
            Console.ReadKey();
        }

        /// <summary>
        /// 发送信息
        /// </summary>
        /// <param name="obj"></param>
        private static void SendMessage(object obj)
        {
            try
            {
                string message = obj.ToString();
                string[] array = message.Split(' ');
                IPAddress iPAddress = IPAddress.Parse(array[0]);
                int port = int.Parse(array[1]);
                byte[] sendbytes = Encoding.Unicode.GetBytes(array[2]);
                IPEndPoint remoteIpep = new IPEndPoint(iPAddress, port); // 发送到的IP地址和端口号
                udpcSend.Send(sendbytes, sendbytes.Length, remoteIpep);
            }
            catch { }
        }

        /// <summary>
        /// 开关：在监听UDP报文阶段为true，否则为false
        /// </summary>
        static bool IsUdpcRecvStart = false;
        /// <summary>
        /// 线程：不断监听UDP报文
        /// </summary>
        static Thread thrRecv;

        private static void StartReceive()
        {
            if (!IsUdpcRecvStart) // 未监听的情况，开始监听
            {
                thrRecv = new Thread(ReceiveMessage);
                thrRecv.Start();
                IsUdpcRecvStart = true;
                Console.WriteLine("UDP监听器已成功启动");
            }
        }

        private static void StopReceive()
        {
            if (IsUdpcRecvStart)
            {
                thrRecv.Abort(); // 必须先关闭这个线程，否则会异常
                IsUdpcRecvStart = false;
                Console.WriteLine("UDP监听器已成功关闭");
            }
        }

        /// <summary>
        /// 接收数据
        /// </summary>
        /// <param name="obj"></param>
        private static void ReceiveMessage(object obj)
        {
            while (IsUdpcRecvStart)
            {
                try
                {
                    byte[] bytRecv = udpcSend.Receive(ref localIpep);
                    string message = Encoding.Unicode.GetString(bytRecv, 0, bytRecv.Length);
                    Console.WriteLine(string.Format("{0}[{1}]", localIpep, message));
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    break;
                }
            }
        }
    }
}